/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.sentry;

import io.sentry.protocol.SentryId;
import io.sentry.util.Objects;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * TransactionContext
 *
 * @since 2021-06-02
 **/
public final class TransactionContext extends SpanContext {
    private final @NotNull String name;
    private @Nullable Boolean parentSampled;

    /**
     * constructor
     *
     * @param name String
     * @param operation String
     */
    public TransactionContext(final @NotNull String name, final @NotNull String operation) {
        super(operation);
        this.name = Objects.requireNonNull(name, "name is required");
        this.parentSampled = null;
    }

    /**
     * Creates {@link TransactionContext} with explicit sampling decision.
     *
     * @param name - transaction name
     * @param operation - operation
     * @param sampled - sampling decision
     */
    public TransactionContext(
        final @NotNull String name,
        final @NotNull String operation,
        final @Nullable Boolean sampled) {
        super(operation);
        this.name = Objects.requireNonNull(name, "name is required");
        this.setSampled(sampled);
    }

    /**
     * constructor
     *
     * @param name String
     * @param operation String
     * @param traceId SentryId
     * @param spanId SpanId
     * @param parentSpanId SpanId
     * @param parentSampled Boolean
     */
    private TransactionContext(
        final @NotNull String name,
        final @NotNull String operation,
        final @NotNull SentryId traceId,
        final @NotNull SpanId spanId,
        final @Nullable SpanId parentSpanId,
        final @Nullable Boolean parentSampled) {
        super(traceId, spanId, operation, parentSpanId, null);
        this.name = Objects.requireNonNull(name, "name is required");
        this.parentSampled = parentSampled;
    }

    /**
     * Creates {@link TransactionContext} from sentry-trace header.
     *
     * @param name - the transaction name
     * @param operation - the operation
     * @param sentryTrace - the sentry-trace header
     * @return the transaction contexts
     */
    public static @NotNull TransactionContext fromSentryTrace(
        final @NotNull String name,
        final @NotNull String operation,
        final @NotNull SentryTraceHeader sentryTrace) {
        return new TransactionContext(
            name,
            operation,
            sentryTrace.getTraceId(),
            new SpanId(),
            sentryTrace.getSpanId(),
            sentryTrace.isSampled());
    }

    public @NotNull String getName() {
        return name;
    }

    public @Nullable Boolean getParentSampled() {
        return parentSampled;
    }

    public void setParentSampled(final @Nullable Boolean parentSampled) {
        this.parentSampled = parentSampled;
    }
}
